﻿using System.Dynamic;
using System.Text.RegularExpressions;

namespace Lib.Common;
/// <summary>
/// 数据验证类
/// </summary>
public static partial class DataValidate {

    /// <summary>
    /// 是否为空（Null、DBNull.Value）
    /// </summary>
    public static bool IsEmpty(this object Value) {
        if (Value == null || Value == DBNull.Value || string.IsNullOrEmpty(Value.ToString())) {
            return true;
        }
        return false;
    }
    /// <summary>
    /// 是否为空（Null、string.Empty）
    /// </summary>
    public static bool IsEmpty(this string Value) {
        return string.IsNullOrEmpty(Value);
    }
    /// <summary>
    /// 验证是否为布尔值类型
    /// </summary>
    public static bool IsBoolean(this string Value) {
        if (string.IsNullOrEmpty(Value)) {
            return false;
        }
        return string.Compare(Value, "false", true) == 0 || string.Compare(Value, "true", true) == 0;
    }
    /// <summary>
    /// 验证是否为时间格式
    /// </summary>
    public static bool IsDateTime(this string Value) {
        if (string.IsNullOrEmpty(Value)) {
            return false;
        }
        if (DateTime.TryParse(Value, out _)) {
            return true;
        }
        return false;
    }

    /// <summary>
    /// 验证是否为数字, 包括整数、浮点数、正负数
    /// </summary>
    public static bool IsDigit(this string Value) {
        if (string.IsNullOrEmpty(Value)) {
            return false;
        }
        return RegExDigit().IsMatch(Value);
    }
    /// <summary>
    /// 验证是否为整数, 默认验证无符号类型
    /// </summary>
    public static bool IsNumber(this string Value, bool Sign = false) {
        if (string.IsNullOrEmpty(Value)) {
            return false;
        }
        if (Sign) {
            return RegExSignNumber().IsMatch(Value);
        } else {
            return RegExNumber().IsMatch(Value);
        }
    }
    /// <summary>
    /// 验证是否为浮点数, 包含小数, 默认验证无符号类型
    /// </summary>
    public static bool IsDecimal(this string Value, bool Sign = false) {
        if (string.IsNullOrEmpty(Value)) {
            return false;
        }
        if (Sign) {
            return RegExSignDecimal().IsMatch(Value);
        } else {
            return RegExDecimal().IsMatch(Value);
        }

    }
    /// <summary>
    /// 验证是否为货币格式
    /// </summary>
    public static bool IsMoney(this string Value, int Index = 2) {
        if (string.IsNullOrEmpty(Value)) {
            return false;
        }
        return Regex.IsMatch(Value, string.Concat("^-?[0-9]+(\\.?[0-9]{1,", Index, "})?$"));
    }
    /// <summary>
    /// 验证是否含有中文字
    /// </summary>
    public static bool IsHasChinese(this string Value) {
        if (string.IsNullOrEmpty(Value)) {
            return false;
        }
        return RegExHasChinese().IsMatch(Value);
    }
    /// <summary>
    /// 验证是否含有数字 [0-9]
    /// </summary>
    public static bool IsHasNumber(this string Value) {
        if (string.IsNullOrEmpty(Value)) {
            return false;
        }
        return RegExHasNumber().IsMatch(Value);
    }
    /// <summary>
    /// 验证是否含有字母 [a-zA-Z]
    /// </summary>
    public static bool IsHasLetter(this string Data) {
        if (string.IsNullOrEmpty(Data)) {
            return false;
        }
        return RegExHasLetter().IsMatch(Data);
    }
    /// <summary>
    /// 验证是否含有字母数字 [a-zA-Z_0-9]
    /// </summary>
    public static bool IsHasNumberLetter(this string Data) {
        if (string.IsNullOrEmpty(Data)) {
            return false;
        }
        return RegExHasNumberLetter().IsMatch(Data);
    }
    /// <summary>
    /// 验证是否为有效的数字类型字符串 (如: 12,35,87,12,45)
    /// </summary>
    public static bool IsNumberChar(this string Value) {
        if (string.IsNullOrEmpty(Value)) {
            return false;
        }
        return RegExNumberChar().IsMatch(Value);
    }

    /// <summary>
    /// 验证数据是否跟指定的正则表达式模式匹配
    /// </summary>
    public static bool RegEx(this string Value, string Pattern) {
        if (string.IsNullOrEmpty(Value) || string.IsNullOrEmpty(Pattern)) {
            return false;
        }
        return Regex.IsMatch(Value, Pattern);
    }
    /// <summary>
    /// 检测当前字符是否在以“间隔符号”分开的字符串中，如(xx,xxx,xxx,xxx)
    /// </summary>
    public static bool IsContainsChar(this string Source, string Char, string Symbol = ",") {
        bool Result = false;
        if (string.IsNullOrEmpty(Symbol)) {
            Symbol = ",";
        }
        if (!string.IsNullOrEmpty(Char) && !string.IsNullOrEmpty(Source)) {
            if (string.Concat(Symbol, Source, Symbol).Contains(string.Concat(Symbol, Char, Symbol))) {
                return true;
            }
        }
        return Result;
    }
    /// <summary>
    /// 检测是否为数字类型（包含枚举类型）
    /// </summary>
    public static bool IsNumber(this object e) {
        if (e != null) {
            return e.GetType().IsNumber();
        }
        return false;
    }
    /// <summary>
    /// 检测是否为数字类型（包含枚举类型）
    /// </summary>
    public static bool IsNumber(this Type e) {
        if (!e.IsValueType) {
            return false;
        }
        return e.Name switch {
            "Char" or "Boolean" or "DateTime" or "Guid" => false,
            _ => true,
        };
    }

    /// <summary>
    /// 是否包含指定枚举项
    /// </summary>
    public static bool Contains<T>(this Enum e, T Value) {
        if ((Convert.ToInt32(e) | Convert.ToInt32(Value)) == Convert.ToInt32(e)) {
            return true;
        } else {
            return false;
        }
    }
    /// <summary>
    /// 动态类型对象是否包含指定名称的属性
    /// </summary>
    public static bool ContainsKey(this ExpandoObject e, string Key) {
        if (e != null) {
            if (((IDictionary<string, object>)e).ContainsKey(Key)) {
                return true;
            }
        }
        return false;
    }



    /// <summary>
    /// 是否基元类型（包括数字、布尔、字符串、时间、枚举、GUID）
    /// </summary>
    public static bool IsPrimitiveType(this Type e) {
        if (e.IsValueType || e.Name == "String") {
            return true;
        }
        return false;
    }
    /// <summary>
    /// 是否可空类型
    /// </summary>
    public static bool IsNullable(this Type e) {
        if (e.IsGenericType && Nullable.GetUnderlyingType(e) != null) {
            return true;
        }
        return false;
    }
    /// <summary>
    /// 是否匿名类型（new { K1 = V1, K2 = V2,...}）
    /// </summary>
    public static bool IsAnonymousType(Type e) {
        if (e.IsClass && e.IsGenericType && e.Name.Contains("__AnonymousType")) {
            return true;
        }
        return false;
    }
    /// <summary>
    /// 是否动态类型（new ExpandoObject()）
    /// </summary>
    public static bool IsDynamicType(Type e) {
        if (e.IsClass && e.Name == "ExpandoObject") {
            return true;
        }
        return false;
    }
    /// <summary>
    /// 是否实体类（排除：值类型、字符串、数组、列表、字典、队列、链表等数据结构）
    /// </summary>
    public static bool IsClassType(Type e) {
        if (e.IsValueType || e.IsArray) {
            return false;
        }
        if (e.IsClass) {
            if (e.Name == "String" || e.Name == "HeaderDictionary") {
                return false;
            }
            if (e.FullName.StartsWith("System.")) {
                return false;
            }
            if (e.Name.Contains("__AnonymousType")) {
                return false;
            }
            return true;
        }
        if (e.IsInterface) {
            if (e.FullName.StartsWith("System.") || e.Name == "IHeaderDictionary") {
                return false;
            }
        }
        return false;
    }
    /// <summary>
    /// 是否集合类型（包括：Array、ArrayList、List、Dictionary,Hashtable、HeaderDictionary、NameValueCollection、Stack、Queue、HashSet、SortedSet、SortedList、LinkedList）
    /// </summary>
    public static bool IsCollectionType(Type e) {
        if (e.IsValueType) {
            return false;
        }
        if (e.IsClass) {
            if (e.IsArray) {
                return true;
            }
            if (e.Name == "String") {
                return false;
            }
            if (e.FullName.StartsWith("System.Collections.") || e.Name == "HeaderDictionary") {
                return true;
            }
        }
        if (e.IsInterface) {
            if (e.FullName.StartsWith("System.Collections.") || e.Name == "IHeaderDictionary") {
                return true;
            }
        }
        return false;
    }
    /// <summary>
    /// 是否数组类型（包括：Array、ArrayList、List、HashSet、SortedSet)
    /// </summary>
    public static bool IsListType(Type e) {
        if (e.IsValueType) {
            return false;
        }
        if (e.IsClass) {
            if (e.IsArray) {
                return true;
            }
            switch (e.Name) {
                case "List`1":
                    return true;
                case "ArrayList":
                    return true;
                case "HashSet`1":
                    return true;
                case "SortedSet`1":
                    return true;
                default:
                    break;
            }
        }
        if (e.IsInterface) {
            if (e.Name.StartsWith("IList")) {
                return true;
            }
        }
        return false;
    }
    /// <summary>
    /// 是否键值对集合类型（包括：Dictionary、Hashtable、SortedList、HeaderDictionary）
    /// </summary>
    public static bool IsKeyValueType(Type e) {
        if (e.IsValueType || e.IsArray) {
            return false;
        }
        if (e.IsClass) {
            switch (e.Name) {
                case "Dictionary`2":
                    return true;
                case "Hashtable":
                    return true;
                case "HeaderDictionary":
                    return true;
                default:
                    break;
            }
            if (e.Name.StartsWith("SortedList")) {
                return true;
            }
        }
        if (e.IsInterface) {
            if (e.Name.StartsWith("IDictionary") || e.Name == "IHeaderDictionary") {
                return true;
            }
        }
        return false;
    }
    /// <summary>
    /// 是否名称值集合类型（包括：NameValueCollection）
    /// </summary>
    public static bool IsNameValueType(Type e) {
        if (e.IsClass) {
            if (e.Name == "NameValueCollection") {
                return true;
            }
        }
        return false;
    }
    /// <summary>
    /// 是否链表类型（包括：LinkedList）
    /// </summary>
    public static bool IsLinkedType(Type e) {
        if (e.IsClass) {
            if (e.Name == "LinkedList`1") {
                return true;
            }
        }
        return false;
    }
    /// <summary>
    /// 是否队列类型（包括：Queue、Stack）
    /// </summary>
    public static bool IsQueueType(Type e) {
        if (e.IsClass) {
            if (e.Name.StartsWith("Stack") || e.Name.StartsWith("Queue")) {
                return true;
            }
        }
        return false;
    }
    
    /// <summary>
    /// 
    /// </summary>
    [GeneratedRegex(@"^[+-]?\d*[.]?\d*$")]
    private static partial Regex RegExDigit();
    
    /// <summary>
    /// 
    /// </summary>
    [GeneratedRegex("^[+-]?[0-9]+$")]
    private static partial Regex RegExSignNumber();
    
    /// <summary>
    /// 
    /// </summary>
    [GeneratedRegex("^[0-9]+$")]
    private static partial Regex RegExNumber();

    /// <summary>
    /// 
    /// </summary>
    [GeneratedRegex("^[+-]?[0-9]+[.]{1}[0-9]+$")]
    private static partial Regex RegExSignDecimal();

    /// <summary>
    /// 
    /// </summary>
    [GeneratedRegex("^[0-9]+[.]{1}[0-9]+$")]
    private static partial Regex RegExDecimal();

    /// <summary>
    /// 
    /// </summary>
    [GeneratedRegex("[\\u4e00-\\u9fa5]")]
    private static partial Regex RegExHasChinese();

    /// <summary>
    /// 
    /// </summary>
    [GeneratedRegex("[0-9]")]
    private static partial Regex RegExHasNumber();

    /// <summary>
    /// 
    /// </summary>
    [GeneratedRegex("[a-zA-Z]")]
    private static partial Regex RegExHasLetter();

    /// <summary>
    /// 
    /// </summary>
    [GeneratedRegex("[a-zA-Z_0-9]")]
    private static partial Regex RegExHasNumberLetter();

    /// <summary>
    /// 
    /// </summary>
    [GeneratedRegex(@"^[\d\|\s,-]*$", RegexOptions.IgnoreCase, "zh-CN")]
    private static partial Regex RegExNumberChar();
}

